<?php
/**
 * @Author: rocky
 * @Copyright: 广州拓冠科技 <http://my8m.com>
 * Date: 2019/7/11
 * Time: 15:15
 */

namespace app\common\service;


use app\common\exception\ErrorException;
use think\Db;
use think\facade\Cache;
use think\facade\Request;


class Token
{

    const IV = 'yHXo48tHnXWSyUY9';
    //密钥
    protected $key = '';
    //过期时间
    protected $expire = 7200;
    //当前token
    protected static $token = '';
    public function __construct()
    {
        $key = env('TOKEN_KEY', 'QsoYEClMJsgOSWUBkSCq26yWkApqSuH3');
        $this->key = substr(md5($key), 8, 16);
        $this->expire = env('TOKEN_EXPIRE', 7200);
    }

    /**
     * 退出token
     * @Author: rocky
     * 2019/12/7 13:37
     * @param $token
     * @return mixed
     */
    public function logout($token=''){
        if(empty($token)){
            return Cache::set(md5(self::$token),time(),$this->expire);
        }else{
            return Cache::set(md5($token),time(),$this->expire);
        }
    }
    /**
     * 获取当前token
     * @Author: rocky
     * 2019/11/4 16:31
     * @return $token
     */
    public function get()
    {
        return self::$token;
    }
    /**
     * 设置token
     * @Author: rocky
     * 2019/11/4 16:31
     * @param $token
     */
    public function set($token)
    {
        self::$token = $token;
        return true;
    }

    /**
     * 清除token
     * @Author: rocky
     * 2019/11/4 16:31
     * @param $token
     */
    public function clear()
    {
        self::$token = '';
        return true;
    }
    /**
     * 返回token
     * @Author: rocky
     * @Copyright: 广州拓冠科技 <http://my8m.com>
     * 2019/7/11 15:27
     * @param $data
     * @return array
     */
    public function encode($data)
    {
        $data['expire'] = time() + $this->expire;
        $str = json_encode($data);
        $token = openssl_encrypt($str, 'aes-256-cbc', $this->key, 0, self::IV);
        if(isset($data['id'])){
            $cacheKey = 'last_auth_token_'.$data['id'];
            //开启唯一登录就将上次token加入黑名单
            if(Cache::has($cacheKey) && env('TOKEN_UNIQUE',false)){
                $logoutToken = Cache::get($cacheKey);
                $this->logout($logoutToken);
            }
            //保存最新token
            Cache::set($cacheKey,$token,$this->expire);
        }
        return [
            'token' => $token,
            'expire' => $this->expire,
            'phone' => $data['phone']
        ];
    }

    /**
     * 解密TOKEN
     * @Author: rocky
     * @Copyright: 广州拓冠科技 <http://my8m.com>
     * 2019/7/11 18:52
     * @param $token
     * @return string
     */
    public function decode($token)
    {
        $str = openssl_decrypt($token, 'aes-256-cbc', $this->key, 0, self::IV);
        if ($str === false) {
            return false;
        } else {
            return json_decode($str, true);
        }
    }

    // 会员等级
    public function level($store_id = 0){
        // $member =  Db::name('ShopMember')->where('store_id',$store_id)->where('uid',$this->id())->where('status',1)->order('id','asc')->find();
        $member =  Db::name('ShopMember')->where('uid',$this->id())->where('status',1)->order('id','asc')->find();
        if ($member){
            $name = Db::name('ShopMemberCard')->where('id',$member['card_id'])->find()['name'];
            return $name.'会员';
        }else{
            return '';
        }
    }
    
    /**
     * 获取用户会员信息
     * 2019/7/12 17:18
     * @return bool
     */
    public function member($store_id = 0)
    {
        // $member =  Db::name('ShopMember')->where('store_id',$store_id)->where('uid',$this->id())->where('status',1)->order('id','asc')->select();
        $member =  Db::name('ShopMember')->where('uid',$this->id())->where('status',1)->order('id','asc')->select();
        if ($member){
            foreach ($member as $value){
                //判断会员卡是否过期
                if ($value['expire_time'] >= time()){
                    $expire_time = date('Y-m-d',$value['expire_time']);
                    return [true,$expire_time];
                }else{
                    $expire_time = date('Y-m-d',$value['expire_time']);
                    return [false,$expire_time];
                }
            }
        }else{
            return [false,''];
        }
    }
    
    /**
     * 获取会员卡Id
     * @Author: rocky
     * 2019/7/12 17:18
     * @return bool
     */
    public function memberId($store_id = 0)
    {
        // $member =  Db::name('ShopMember')->where('store_id',$store_id)->where('uid',$this->id())->where('status',1)->order('id','asc')->select();
        $member =  Db::name('ShopMember')->where('uid',$this->id())->where('status',1)->order('id','asc')->select();
        if ($member){
            foreach ($member as $value){
                if ($value['expire_time'] >= time()){
                    return [true,$value['id']];
                }
            }
        }else{
            return [false,''];
        }
    }
    
    /**
     * 获取用户剩余洗衣次数
     * @Author: rocky
     * 2019/7/12 17:18
     * @return bool
     */
    public function laundryNum($store_id = 0)
    {
        // $num = model('ShopMember')->where('store_id',$store_id)->where('uid',$this->id())->where('status',1)->removeOption('order')->order('id','asc')->select();
        //$num = model('ShopMember')->where('uid',$this->id())->where('status',1)->removeOption('order')->order('id','asc')->select();
        $num = model('ShopMember')->where('uid',$this->id())->where('status',1)->select();
        //halt($num);
        if ($num){
            $all_num = 0;
            foreach ($num as $value){
                if ($value['expire_time'] >= time()){
                    $item_num = $value['total_num'] - $value['use_num'];
                    $all_num +=$item_num;
                    //return $value['residue_num'];
                }
            }
            return $all_num;
        }else{
            return 0;
        }
    }

    /**
     * 获取用户免费洗被子次数
     * @Author: rocky
     * 2019/7/12 17:18
     * @return bool
     */
    public function freeNum($store_id = 0)
    {
        // $num = model('ShopMember')->where('store_id',$store_id)->where('uid',$this->id())->where('status',1)->removeOption('order')->order('id','asc')->select();
        $num = model('ShopMember')->where('uid',$this->id())->where('status',1)->removeOption('order')->order('id','asc')->select();
        if ($num){
            foreach ($num as $value){
                if ($value['expire_time'] >= time()){
                    return $value['free_num'] - $value['free_use_num'];
                }
            }
        }else{
            return 0;
        }
    }

    /**
     * 验证token
     * @Author: rocky
     * @Copyright: 广州拓冠科技 <http://my8m.com>
     * 2019/7/12 17:12
     * @param $token 需要验证的token
     * @return bool|\think\response\Json 通过返回真
     */
    public function auth($bool = true)
    {
        $token = self::$token ? self::$token : Request::header('Authorization');
        if (empty($token)) {
            throw new ErrorException(4000,200);
        }
        $data = $this->decode($token);
        if ($data === false || Cache::has(md5($token))) {
            throw new ErrorException(4000,200);
        }
        if ($data['expire'] < time()) {
            throw new ErrorException(4001,200);
        }
        if ($bool) {
            return true;
        } else {
            return $data;
        }

    }

    /**
     * 获取Token保存数组key下的值
     * @Author: rocky
     * @Copyright: 广州拓冠科技 <http://my8m.com>
     * 2019/7/12 17:17
     * @param $name
     * @return bool
     */
    public function getVar($name)
    {
        $token = self::$token ? self::$token : Request::header('Authorization');
        $data = $this->decode($token);
        if (isset($data[$name])) {
            return $data[$name];
        } else {
            return null;
        }
    }

    /**
     * 获取用户id
     * @Author: rocky
     * @Copyright: 广州拓冠科技 <http://my8m.com>
     * 2019/7/12 17:18
     * @return bool
     */
    public function id()
    {
        return $this->getVar('id');
    }

    /**
     * 返回用户模型
     * @return mixed
     */
    public function user($lock = false)
    {
        if (is_null($this->id())) {
            return null;
        }
        $user = model('user');
        return $user->lock($lock)->find($this->id());
    }
}